{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import numpy as np\n",
    "from torch.utils.data import Dataset\n",
    "from torch.utils.data import DataLoader\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "\n",
    "# prepare dataset\n",
    "\n",
    "'''\n",
    "Dataset是一个抽象函数，不能直接实例化，所以我们要创建一个自己类，继承Dataset\n",
    "继承Dataset后我们必须实现三个函数：\n",
    "__init__()是初始化函数，之后我们可以提供数据集路径进行数据的加载\n",
    "__getitem__()帮助我们通过索引找到某个样本\n",
    "__len__()帮助我们返回数据集大小\n",
    "'''\n",
    " \n",
    "class DiabetesDataset(Dataset):\n",
    "    def __init__(self, filepath):\n",
    "        xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32)\n",
    "        self.len = xy.shape[0] # shape(多少行，多少列)\n",
    "        self.x_data = torch.from_numpy(xy[:, :-1])\n",
    "        self.y_data = torch.from_numpy(xy[:, [-1]])\n",
    " \n",
    "    def __getitem__(self, index):\n",
    "        return self.x_data[index], self.y_data[index]\n",
    " \n",
    "    def __len__(self):\n",
    "        return self.len\n",
    " \n",
    "\n",
    "dataset = DiabetesDataset('dataset/diabetes.csv')\n",
    "#用DataLoader为数据进行分组，batch_size是一个组中有多少个样本，shuffle表示要不要对样本进行随机排列\n",
    "#一般来说，训练集我们随机排列，测试集不。num_workers表示我们可以用多少进程并行的运算\n",
    "train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=0) #num_workers 多线程\n",
    " \n",
    " \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "# design model using class\n",
    "class Model(torch.nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Model, self).__init__()\n",
    "        self.linear1 = torch.nn.Linear(8, 6)\n",
    "        self.linear2 = torch.nn.Linear(6, 4)\n",
    "        self.linear3 = torch.nn.Linear(4, 1)\n",
    "        self.sigmoid = torch.nn.Sigmoid()\n",
    " \n",
    "    def forward(self, x):\n",
    "        x = self.sigmoid(self.linear1(x))\n",
    "        x = self.sigmoid(self.linear2(x))\n",
    "        x = self.sigmoid(self.linear3(x))\n",
    "        return x\n",
    " \n",
    " \n",
    "model = Model()\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# construct loss and optimizer\n",
    "criterion = torch.nn.BCELoss(reduction='mean')\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.01)\n",
    " "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 0 0.700600266456604\n",
      "0 1 0.6934558749198914\n",
      "0 2 0.6985839009284973\n",
      "0 3 0.6978885531425476\n",
      "0 4 0.6965387463569641\n",
      "0 5 0.6946659088134766\n",
      "0 6 0.6945940852165222\n",
      "0 7 0.6941839456558228\n",
      "0 8 0.6935600638389587\n",
      "0 9 0.6938855051994324\n",
      "0 10 0.6935380697250366\n",
      "0 11 0.6920198798179626\n",
      "0 12 0.6918224096298218\n",
      "0 13 0.6903005838394165\n",
      "0 14 0.6898937225341797\n",
      "0 15 0.6911400556564331\n",
      "0 16 0.6905520558357239\n",
      "0 17 0.6887757778167725\n",
      "0 18 0.6893635988235474\n",
      "0 19 0.6893026828765869\n",
      "0 20 0.6883663535118103\n",
      "0 21 0.686737596988678\n",
      "0 22 0.6882948279380798\n",
      "0 23 0.6946994066238403\n",
      "1 0 0.6912367343902588\n",
      "1 1 0.6855381727218628\n",
      "1 2 0.6846035122871399\n",
      "1 3 0.6808702349662781\n",
      "1 4 0.6813540458679199\n",
      "1 5 0.68841952085495\n",
      "1 6 0.6707568764686584\n",
      "1 7 0.6899784207344055\n",
      "1 8 0.6897026300430298\n",
      "1 9 0.6876884698867798\n",
      "1 10 0.6871317028999329\n",
      "1 11 0.6805782914161682\n",
      "1 12 0.6820083856582642\n",
      "1 13 0.6715496778488159\n",
      "1 14 0.7027878761291504\n",
      "1 15 0.6759334802627563\n",
      "1 16 0.678095281124115\n",
      "1 17 0.6832297444343567\n",
      "1 18 0.6974135041236877\n",
      "1 19 0.6749867796897888\n",
      "1 20 0.6737316250801086\n",
      "1 21 0.6700246334075928\n",
      "1 22 0.6784742474555969\n",
      "1 23 0.6837866306304932\n",
      "2 0 0.6783747673034668\n",
      "2 1 0.6811864376068115\n",
      "2 2 0.6811957359313965\n",
      "2 3 0.6701090931892395\n",
      "2 4 0.6877418756484985\n",
      "2 5 0.6692360639572144\n",
      "2 6 0.6993098258972168\n",
      "2 7 0.672375500202179\n",
      "2 8 0.6722803711891174\n",
      "2 9 0.6877039074897766\n",
      "2 10 0.6553963422775269\n",
      "2 11 0.6788959503173828\n",
      "2 12 0.6872484683990479\n",
      "2 13 0.6657975316047668\n",
      "2 14 0.6784389019012451\n",
      "2 15 0.6560933589935303\n",
      "2 16 0.6731969714164734\n",
      "2 17 0.6778097748756409\n",
      "2 18 0.6633931398391724\n",
      "2 19 0.6915673017501831\n",
      "2 20 0.6630182862281799\n",
      "2 21 0.6618135571479797\n",
      "2 22 0.6561409831047058\n",
      "2 23 0.7006784677505493\n",
      "3 0 0.67107093334198\n",
      "3 1 0.6966278553009033\n",
      "3 2 0.6760060787200928\n",
      "3 3 0.6600579023361206\n",
      "3 4 0.6594880819320679\n",
      "3 5 0.6863071322441101\n",
      "3 6 0.6863658428192139\n",
      "3 7 0.6587241291999817\n",
      "3 8 0.6752124428749084\n",
      "3 9 0.6693204045295715\n",
      "3 10 0.6347267627716064\n",
      "3 11 0.668778121471405\n",
      "3 12 0.6684072017669678\n",
      "3 13 0.6859119534492493\n",
      "3 14 0.6498746871948242\n",
      "3 15 0.6613081097602844\n",
      "3 16 0.6735536456108093\n",
      "3 17 0.6796806454658508\n",
      "3 18 0.6670783758163452\n",
      "3 19 0.6731215715408325\n",
      "3 20 0.6860297918319702\n",
      "3 21 0.6473756432533264\n",
      "3 22 0.6462095975875854\n",
      "3 23 0.6760970950126648\n",
      "4 0 0.6314194798469543\n",
      "4 1 0.6650127172470093\n",
      "4 2 0.6717869639396667\n",
      "4 3 0.6993938684463501\n",
      "4 4 0.6508955359458923\n",
      "4 5 0.6716467142105103\n",
      "4 6 0.6925221085548401\n",
      "4 7 0.6572422385215759\n",
      "4 8 0.6570220589637756\n",
      "4 9 0.6419786810874939\n",
      "4 10 0.6861323714256287\n",
      "4 11 0.6338576674461365\n",
      "4 12 0.6631110310554504\n",
      "4 13 0.6705833077430725\n",
      "4 14 0.6319760084152222\n",
      "4 15 0.6700513958930969\n",
      "4 16 0.6778053045272827\n",
      "4 17 0.685945987701416\n",
      "4 18 0.6386496424674988\n",
      "4 19 0.66190505027771\n",
      "4 20 0.6778727769851685\n",
      "4 21 0.6616153717041016\n",
      "4 22 0.6857525110244751\n",
      "4 23 0.6508870720863342\n",
      "5 0 0.6697471141815186\n",
      "5 1 0.6611539721488953\n",
      "5 2 0.6443412899971008\n",
      "5 3 0.6860480904579163\n",
      "5 4 0.6690493822097778\n",
      "5 5 0.6096212267875671\n",
      "5 6 0.6685571074485779\n",
      "5 7 0.6597338914871216\n",
      "5 8 0.6684530377388\n",
      "5 9 0.6332893371582031\n",
      "5 10 0.6591092348098755\n",
      "5 11 0.640930712223053\n",
      "5 12 0.7128550410270691\n",
      "5 13 0.6412814855575562\n",
      "5 14 0.6495465636253357\n",
      "5 15 0.66786789894104\n",
      "5 16 0.6403566002845764\n",
      "5 17 0.6766730546951294\n",
      "5 18 0.6582130193710327\n",
      "5 19 0.6491755247116089\n",
      "5 20 0.6672153472900391\n",
      "5 21 0.6391763091087341\n",
      "5 22 0.6762633919715881\n",
      "5 23 0.7116498351097107\n",
      "6 0 0.6578813195228577\n",
      "6 1 0.6478613018989563\n",
      "6 2 0.6672705411911011\n",
      "6 3 0.6282946467399597\n",
      "6 4 0.6669142246246338\n",
      "6 5 0.686838686466217\n",
      "6 6 0.61851567029953\n",
      "6 7 0.6763514876365662\n",
      "6 8 0.6765504479408264\n",
      "6 9 0.656700074672699\n",
      "6 10 0.6662746071815491\n",
      "6 11 0.6662402749061584\n",
      "6 12 0.6365461349487305\n",
      "6 13 0.6765171885490417\n",
      "6 14 0.6860041618347168\n",
      "6 15 0.645642876625061\n",
      "6 16 0.6759551167488098\n",
      "6 17 0.6761820316314697\n",
      "6 18 0.6558395624160767\n",
      "6 19 0.645613431930542\n",
      "6 20 0.5834234952926636\n",
      "6 21 0.6344102621078491\n",
      "6 22 0.6231034994125366\n",
      "6 23 0.7445909380912781\n",
      "7 0 0.6444764733314514\n",
      "7 1 0.622925341129303\n",
      "7 2 0.6330402493476868\n",
      "7 3 0.5680111050605774\n",
      "7 4 0.70881587266922\n",
      "7 5 0.6432338953018188\n",
      "7 6 0.6538897156715393\n",
      "7 7 0.6536917090415955\n",
      "7 8 0.6537121534347534\n",
      "7 9 0.7093444466590881\n",
      "7 10 0.6091286540031433\n",
      "7 11 0.686906099319458\n",
      "7 12 0.7427246570587158\n",
      "7 13 0.609617292881012\n",
      "7 14 0.619981586933136\n",
      "7 15 0.7324442267417908\n",
      "7 16 0.6093246936798096\n",
      "7 17 0.6532222032546997\n",
      "7 18 0.6761564016342163\n",
      "7 19 0.6305226683616638\n",
      "7 20 0.6530174016952515\n",
      "7 21 0.6874261498451233\n",
      "7 22 0.6071730256080627\n",
      "7 23 0.7348418831825256\n",
      "8 0 0.6297943592071533\n",
      "8 1 0.6758831143379211\n",
      "8 2 0.6640329360961914\n",
      "8 3 0.6411434412002563\n",
      "8 4 0.6643676161766052\n",
      "8 5 0.6294507384300232\n",
      "8 6 0.6522933840751648\n",
      "8 7 0.6520751714706421\n",
      "8 8 0.7227343320846558\n",
      "8 9 0.6640141606330872\n",
      "8 10 0.6173226237297058\n",
      "8 11 0.56923508644104\n",
      "8 12 0.6638337969779968\n",
      "8 13 0.6759265065193176\n",
      "8 14 0.6756147742271423\n",
      "8 15 0.6755545735359192\n",
      "8 16 0.6274129152297974\n",
      "8 17 0.6396100521087646\n",
      "8 18 0.6516587138175964\n",
      "8 19 0.6144797205924988\n",
      "8 20 0.6758455634117126\n",
      "8 21 0.6881918907165527\n",
      "8 22 0.6267030835151672\n",
      "8 23 0.6867170333862305\n",
      "9 0 0.6881163716316223\n",
      "9 1 0.6263090372085571\n",
      "9 2 0.6385403871536255\n",
      "9 3 0.6759718656539917\n",
      "9 4 0.6633246541023254\n",
      "9 5 0.688064694404602\n",
      "9 6 0.6380957961082458\n",
      "9 7 0.6635456085205078\n",
      "9 8 0.6884933710098267\n",
      "9 9 0.6010648012161255\n",
      "9 10 0.6506503820419312\n",
      "9 11 0.7263957262039185\n",
      "9 12 0.6253751516342163\n",
      "9 13 0.6632453799247742\n",
      "9 14 0.638042688369751\n",
      "9 15 0.6506693959236145\n",
      "9 16 0.6376516819000244\n",
      "9 17 0.6500886082649231\n",
      "9 18 0.6891046166419983\n",
      "9 19 0.6630045175552368\n",
      "9 20 0.6372189521789551\n",
      "9 21 0.6110901832580566\n",
      "9 22 0.6240295171737671\n",
      "9 23 0.5787081718444824\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# training cycle forward, backward, update\n",
    "\n",
    "if __name__ == '__main__':\n",
    "    epoch_list = []\n",
    "    loss_list = []\n",
    "    for epoch in range(10):\n",
    "        for i, data in enumerate(train_loader, 0): # train_loader 是先shuffle后mini_batch\n",
    "            #data为元组，dataset类定义getitem返回值(x,y)\n",
    "            inputs, labels = data\n",
    "            y_pred = model(inputs)\n",
    "            loss = criterion(y_pred, labels)\n",
    "            print(epoch, i, loss.item())\n",
    " \n",
    "            optimizer.zero_grad()\n",
    "            loss.backward()\n",
    "            optimizer.step()\n",
    "        epoch_list.append(epoch)\n",
    "        loss_list.append(loss.item())\n",
    "    plt.plot(epoch_list, loss_list)\n",
    "    plt.ylabel('loss')\n",
    "    plt.xlabel('epoch')\n",
    "    plt.show()\n",
    "        "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
